Change the default output location to target/debug
authorAlex Crichton <alex@alexcrichton.com>
Tue, 3 Mar 2015 21:46:02 +0000 (13:46 -0800)
committerAlex Crichton <alex@alexcrichton.com>
Fri, 6 Mar 2015 18:53:43 +0000 (10:53 -0800)
This commit now funnels all output of Cargo by default to be in `target/debug`
instead of the bare `target` directory. This change is targeted at raising
awareness of whether a debug build is being used (as opposed to a release
build). It is also aimed at remedying a common scenario where `cargo build` is
followed by `cargo build --release` and then the debug binaries are run by
accident.

This does not yet explore the option of providing symlinks to the most recent
build, hence this commit is a breaking change due to the restructuring of the
layout of the output.

Note that this commit does **not** change the output location for documentation.
All output of `cargo doc` continues to be funneled into the `target/doc`
directory.

Closes #785

14 files changed:
src/cargo/core/manifest.rs
src/cargo/ops/cargo_run.rs
src/cargo/ops/cargo_rustc/layout.rs
src/cargo/ops/cargo_rustc/mod.rs
tests/support/mod.rs
tests/test_cargo_build_lib.rs
tests/test_cargo_compile.rs
tests/test_cargo_compile_custom_build.rs
tests/test_cargo_compile_plugins.rs
tests/test_cargo_cross_compile.rs
tests/test_cargo_new.rs
tests/test_cargo_profiles.rs
tests/test_cargo_run.rs
tests/test_cargo_test.rs

index eadaa12d9d2b2c2bcc787e385d64031050bb881f..2ae63dcb3f197b5cfd42f031a1cf9c3f7fb4cb8f 100644 (file)
@@ -118,7 +118,7 @@ pub struct Profile {
     test: bool,
     doctest: bool,
     doc: bool,
-    dest: Option<String>,
+    dest: String,
     for_host: bool,
     harness: bool, // whether to use the test harness (--test)
     custom_build: bool,
@@ -135,7 +135,7 @@ impl Profile {
             rpath: false,
             test: false,
             doc: false,
-            dest: None,
+            dest: "debug".to_string(),
             for_host: false,
             doctest: false,
             custom_build: false,
@@ -157,7 +157,6 @@ impl Profile {
             env: "test".to_string(),
             debug: true,
             test: true,
-            dest: None,
             .. Profile::default()
         }
     }
@@ -172,10 +171,8 @@ impl Profile {
     pub fn default_bench() -> Profile {
         Profile {
             env: "bench".to_string(),
-            opt_level: 3,
             test: true,
-            dest: Some("release".to_string()),
-            .. Profile::default()
+            .. Profile::default_release()
         }
     }
 
@@ -183,7 +180,7 @@ impl Profile {
         Profile {
             env: "release".to_string(),
             opt_level: 3,
-            dest: Some("release".to_string()),
+            dest: "release".to_string(),
             .. Profile::default()
         }
     }
@@ -191,7 +188,6 @@ impl Profile {
     pub fn default_doc() -> Profile {
         Profile {
             env: "doc".to_string(),
-            dest: None,
             doc: true,
             .. Profile::default()
         }
@@ -210,10 +206,7 @@ impl Profile {
     pub fn opt_level(&self) -> u32 { self.opt_level }
     pub fn rpath(&self) -> bool { self.rpath }
     pub fn uses_test_harness(&self) -> bool { self.harness }
-
-    pub fn dest(&self) -> Option<&str> {
-        self.dest.as_ref().map(|d| d.as_slice())
-    }
+    pub fn dest(&self) -> &str { &self.dest }
 
     pub fn set_opt_level(mut self, level: u32) -> Profile {
         self.opt_level = level;
index 6ad88a8d2de6f9469de9128655391e6997463646..bc6a9d5f279c99d09fa50a0e4c759500855b07a0 100644 (file)
@@ -53,10 +53,8 @@ pub fn run(manifest_path: &Path,
         None => dst,
     };
     let exe = match (bin.profile().dest(), bin.is_example()) {
-        (Some(s), true) => dst.join(s).join("examples").join(bin.name()),
-        (Some(s), false) => dst.join(s).join(bin.name()),
-        (None, true) => dst.join("examples").join(bin.name()),
-        (None, false) => dst.join(bin.name()),
+        (s, true) => dst.join(s).join("examples").join(bin.name()),
+        (s, false) => dst.join(s).join(bin.name()),
     };
     let exe = match exe.relative_from(config.cwd()) {
         Some(path) => path,
index 5aed2effee942fcd2858c3b7f1fff425051bd037..14591df5c963fae0cd47d98139827cb840946a9f 100644 (file)
@@ -68,16 +68,13 @@ pub struct LayoutProxy<'a> {
 }
 
 impl Layout {
-    pub fn new(pkg: &Package, triple: Option<&str>, dest: Option<&str>) -> Layout {
+    pub fn new(pkg: &Package, triple: Option<&str>, dest: &str) -> Layout {
         let mut path = pkg.absolute_target_dir();
         match triple {
             Some(s) => path.push(s),
             None => {}
         }
-        match dest {
-            Some(s) => path.push(s),
-            None => {}
-        }
+        path.push(dest);
         Layout::at(path)
     }
 
index 3d875ba7f0ad142ea0f2cf966ec84dd36a860eac..7553bc46de599fadc5e6d07fa76f58494d8d48d4 100644 (file)
@@ -75,14 +75,14 @@ pub fn rustc_version() -> CargoResult<(String, String)> {
 // This is a temporary assert that ensures the consistency of the arguments
 // given the current limitations of Cargo. The long term fix is to have each
 // Target know the absolute path to the build location.
-fn uniq_target_dest<'a>(targets: &[&'a Target]) -> Option<&'a str> {
-    let mut curr: Option<Option<&str>> = None;
+fn uniq_target_dest<'a>(targets: &[&'a Target]) -> &'a str {
+    let mut curr: Option<&str> = None;
 
     for t in targets.iter().filter(|t| !t.profile().is_custom_build()) {
         let dest = t.profile().dest();
 
         match curr {
-            Some(curr) => assert!(curr == dest),
+            Some(curr) => assert_eq!(curr, dest),
             None => curr = Some(dest)
         }
     }
@@ -483,7 +483,8 @@ fn prepare_rustc(package: &Package, target: &Target, crate_types: Vec<&str>,
 fn rustdoc(package: &Package, target: &Target,
            cx: &mut Context) -> CargoResult<Work> {
     let kind = Kind::Target;
-    let cx_root = cx.layout(package, kind).proxy().dest().join("doc");
+    let cx_root = cx.get_package(cx.resolve.root()).absolute_target_dir()
+                    .join("doc");
     let mut rustdoc = try!(process(CommandType::Rustdoc, package, target, cx));
     rustdoc.arg(&root_path(cx, package, target))
            .cwd(cx.config.cwd())
index fcb0b9595ef33963b233098226a5b7f73027ad60..a225ee68aeef923243b10484371436236380346e 100644 (file)
@@ -103,7 +103,8 @@ impl ProjectBuilder {
     pub fn url(&self) -> Url { path2url(self.root()) }
 
     pub fn bin(&self, b: &str) -> PathBuf {
-        self.build_dir().join(&format!("{}{}", b, env::consts::EXE_SUFFIX))
+        self.build_dir().join("debug").join(&format!("{}{}", b,
+                                                     env::consts::EXE_SUFFIX))
     }
 
     pub fn release_bin(&self, b: &str) -> PathBuf {
@@ -112,8 +113,8 @@ impl ProjectBuilder {
     }
 
     pub fn target_bin(&self, target: &str, b: &str) -> PathBuf {
-        self.build_dir().join(target).join(&format!("{}{}", b,
-                                                    env::consts::EXE_SUFFIX))
+        self.build_dir().join(target).join("debug")
+                        .join(&format!("{}{}", b, env::consts::EXE_SUFFIX))
     }
 
     pub fn build_dir(&self) -> PathBuf {
index 21536d25f365c42c96afc5ded7a0e921b4fce9da..ec20d6e53f26c70494b8df439204dedd89b243fc 100644 (file)
@@ -12,10 +12,10 @@ fn verbose_output_for_lib(p: &ProjectBuilder) -> String {
 {running} `rustc src{sep}lib.rs --crate-name {name} --crate-type lib -g \
         -C metadata=[..] \
         -C extra-filename=-[..] \
-        --out-dir {dir}{sep}target \
+        --out-dir {dir}{sep}target{sep}debug \
         --emit=dep-info,link \
-        -L dependency={dir}{sep}target \
-        -L dependency={dir}{sep}target{sep}deps`
+        -L dependency={dir}{sep}target{sep}debug \
+        -L dependency={dir}{sep}target{sep}debug{sep}deps`
 ",
             running = RUNNING, compiling = COMPILING, sep = old_path::SEP,
             dir = p.root().display(), url = p.url(),
index ae00228211dc3864f74d1a299a6f4b116f750d4f..883b291e08bbaf8f3e6f752f233b42a14efd33e7 100644 (file)
@@ -631,7 +631,7 @@ test!(many_crate_types_old_style_lib_location {
     assert_that(p.cargo_process("build"),
                 execs().with_status(0));
 
-    let files = fs::read_dir(&p.root().join("target")).unwrap();
+    let files = fs::read_dir(&p.root().join("target/debug")).unwrap();
     let mut files: Vec<String> = files.map(|e| e.unwrap().path()).filter_map(|f| {
         match f.file_name().unwrap().to_str().unwrap() {
             "build" | "examples" | "deps" => None,
@@ -669,7 +669,7 @@ test!(many_crate_types_correct {
     assert_that(p.cargo_process("build"),
                 execs().with_status(0));
 
-    let files = fs::read_dir(&p.root().join("target")).unwrap();
+    let files = fs::read_dir(&p.root().join("target/debug")).unwrap();
     let mut files: Vec<String> = files.map(|f| f.unwrap().path()).filter_map(|f| {
         match f.file_name().unwrap().to_str().unwrap() {
             "build" | "examples" | "deps" => None,
@@ -840,10 +840,10 @@ test!(verbose_build {
 {running} `rustc src[..]lib.rs --crate-name test --crate-type lib -g \
         -C metadata=[..] \
         -C extra-filename=-[..] \
-        --out-dir {dir}[..]target \
+        --out-dir {dir}[..]target[..]debug \
         --emit=dep-info,link \
-        -L dependency={dir}[..]target \
-        -L dependency={dir}[..]target[..]deps`
+        -L dependency={dir}[..]target[..]debug \
+        -L dependency={dir}[..]target[..]debug[..]deps`
 ",
 running = RUNNING, compiling = COMPILING,
 dir = p.root().display(),
@@ -1049,7 +1049,7 @@ test!(release_build_ndebug {
 
     assert_that(p.cargo_process("build").arg("--release"),
                 execs().with_status(0));
-    assert_that(process(&p.bin("release/foo")).unwrap(),
+    assert_that(process(&p.release_bin("foo")).unwrap(),
                 execs().with_stdout("fast\n"));
 });
 
index 1eca4f43915764a6cdb8f71b64cf86165ec759ca..b67491f6f8e30a5d07cf0b244bbc811854c7f27c 100644 (file)
@@ -105,7 +105,7 @@ test!(custom_build_env_vars {
                 let _feat = env::var("CARGO_FEATURE_FOO").unwrap();
             }}
         "#,
-        p.root().join("target").join("build").display());
+        p.root().join("target").join("debug").join("build").display());
 
     let p = p.file("bar/build.rs", &file_content);
 
@@ -702,13 +702,13 @@ test!(build_cmd_with_a_build_cmd {
 {running} `rustc build.rs --crate-name build-script-build --crate-type bin \
     -C prefer-dynamic -g \
     --out-dir [..]build[..]foo-[..] --emit=dep-info,link \
-    -L [..]target -L [..]target[..]deps \
+    -L [..]target[..]debug -L [..]target[..]deps \
     --extern a=[..]liba-[..].rlib`
 {running} `[..]foo-[..]build-script-build[..]`
 {running} `rustc [..]lib.rs --crate-name foo --crate-type lib -g \
     -C metadata=[..] -C extra-filename=-[..] \
-    --out-dir [..]target --emit=dep-info,link \
-    -L [..]target -L [..]target[..]deps`
+    --out-dir [..]target[..]debug --emit=dep-info,link \
+    -L [..]target[..]debug -L [..]target[..]deps`
 ", compiling = COMPILING, running = RUNNING).as_slice()));
 });
 
@@ -1024,7 +1024,7 @@ test!(build_script_with_dynamic_native_dependency {
         "#);
     assert_that(build.cargo_process("build"),
                 execs().with_status(0).with_stderr(""));
-    let src = build.root().join("target");
+    let src = build.root().join("target/debug");
     let lib = fs::read_dir(&src).unwrap().map(|s| s.unwrap().path()).find(|lib| {
         let lib = lib.file_name().unwrap().to_str().unwrap();
         lib.starts_with(env::consts::DLL_PREFIX) &&
index 0b093756c28ba456f4baf277506130c6ece7ad48..b983e2cfbdc33d5d802558d3cfa53da1dcd67b7c 100644 (file)
@@ -100,7 +100,7 @@ test!(plugin_with_dynamic_native_dependency {
         "#);
     assert_that(build.cargo_process("build"),
                 execs().with_status(0).with_stderr(""));
-    let src = build.root().join("target");
+    let src = build.root().join("target/debug");
     let lib = fs::read_dir(&src).unwrap().map(|s| s.unwrap().path()).find(|lib| {
         let lib = lib.file_name().unwrap().to_str().unwrap();
         lib.starts_with(env::consts::DLL_PREFIX) &&
index 915f14b60915b72e8ba76c4fdbe020030e46219c..fcb67755823586585d719fecb3bce157d8449606 100644 (file)
@@ -282,12 +282,12 @@ test!(linker_and_ar {
                        .with_stdout(format!("\
 {compiling} foo v0.5.0 ({url})
 {running} `rustc src/foo.rs --crate-name foo --crate-type bin -g \
-    --out-dir {dir}[..]target[..]{target} \
+    --out-dir {dir}[..]target[..]{target}[..]debug \
     --emit=dep-info,link \
     --target {target} \
     -C ar=my-ar-tool -C linker=my-linker-tool \
-    -L dependency={dir}[..]target[..]{target} \
-    -L dependency={dir}[..]target[..]{target}[..]deps`
+    -L dependency={dir}[..]target[..]{target}[..]debug \
+    -L dependency={dir}[..]target[..]{target}[..]debug[..]deps`
 ",
                             running = RUNNING,
                             compiling = COMPILING,
@@ -464,6 +464,8 @@ test!(cross_with_a_build_script {
                 path.pop();
                 assert_eq!(path.filename().unwrap(), b"build");
                 path.pop();
+                assert_eq!(path.filename().unwrap(), b"debug");
+                path.pop();
                 assert_eq!(path.filename().unwrap(), b"{0}");
                 path.pop();
                 assert_eq!(path.filename().unwrap(), b"target");
@@ -636,7 +638,7 @@ test!(build_script_only_host {
 
             fn main() {
                 assert!(env::var("OUT_DIR").unwrap()
-                                             .contains("target/build/d1-"),
+                                             .contains("target/debug/build/d1-"),
                         "bad: {:?}", env::var("OUT_DIR"));
             }
         "#);
index 6821333c0afcbf86aee15fe8b2654e47a7716c7c..ef873526a7b6e5f89a9eec6bdbca3b71ce2f3be6 100644 (file)
@@ -47,7 +47,7 @@ test!(simple_bin {
 
     assert_that(cargo_process("build").cwd(&paths::root().join("foo")),
                 execs().with_status(0));
-    assert_that(&paths::root().join(&format!("foo/target/foo{}",
+    assert_that(&paths::root().join(&format!("foo/target/debug/foo{}",
                                              env::consts::EXE_SUFFIX)),
                 existing_file());
 });
index 827393f92c280e79e5150bfd51b4450185dccb41..1940fe56747c18cf5f9d75e2975324452d339d95 100644 (file)
@@ -33,10 +33,10 @@ test!(profile_overrides {
         -C metadata=[..] \
         -C extra-filename=-[..] \
         -C rpath \
-        --out-dir {dir}{sep}target \
+        --out-dir {dir}{sep}target{sep}debug \
         --emit=dep-info,link \
-        -L dependency={dir}{sep}target \
-        -L dependency={dir}{sep}target{sep}deps`
+        -L dependency={dir}{sep}target{sep}debug \
+        -L dependency={dir}{sep}target{sep}debug{sep}deps`
 ",
 running = RUNNING, compiling = COMPILING, sep = old_path::SEP,
 dir = p.root().display(),
index cc85e968c6cedddbb6d62eb188d27f8ab2d56ca2..7311b4af299edbe3abfab3ff61efb5c765089013 100644 (file)
@@ -22,7 +22,7 @@ test!(simple {
     assert_that(p.cargo_process("run"),
                 execs().with_status(0).with_stdout(format!("\
 {compiling} foo v0.0.1 ({dir})
-{running} `target{sep}foo`
+{running} `target{sep}debug{sep}foo`
 hello
 ",
         compiling = COMPILING,
@@ -123,7 +123,7 @@ test!(specify_name {
     assert_that(p.cargo_process("run").arg("--bin").arg("a"),
                 execs().with_status(0).with_stdout(format!("\
 {compiling} foo v0.0.1 ({dir})
-{running} `target{sep}a`
+{running} `target{sep}debug{sep}a`
 hello a.rs
 ",
         compiling = COMPILING,
@@ -133,7 +133,7 @@ hello a.rs
 
     assert_that(p.cargo("run").arg("--bin").arg("b"),
                 execs().with_status(0).with_stdout(format!("\
-{running} `target{sep}b`
+{running} `target{sep}debug{sep}b`
 hello b.rs
 ",
         running = RUNNING,
@@ -159,7 +159,7 @@ test!(run_example {
     assert_that(p.cargo_process("run").arg("--example").arg("a"),
                 execs().with_status(0).with_stdout(format!("\
 {compiling} foo v0.0.1 ({dir})
-{running} `target{sep}examples{sep}a`
+{running} `target{sep}debug{sep}examples{sep}a`
 example
 ",
         compiling = COMPILING,
@@ -211,7 +211,7 @@ test!(one_bin_multiple_examples {
     assert_that(p.cargo_process("run"),
                 execs().with_status(0).with_stdout(format!("\
 {compiling} foo v0.0.1 ({dir})
-{running} `target{sep}main`
+{running} `target{sep}debug{sep}main`
 hello main.rs
 ",
         compiling = COMPILING,
@@ -301,19 +301,19 @@ fast2
         -g \
         -C metadata=[..] \
         -C extra-filename=[..] \
-        --out-dir {dir}{sep}target{sep}deps \
+        --out-dir {dir}{sep}target{sep}debug{sep}deps \
         --emit=dep-info,link \
-        -L dependency={dir}{sep}target{sep}deps \
-        -L dependency={dir}{sep}target{sep}deps`
+        -L dependency={dir}{sep}target{sep}debug{sep}deps \
+        -L dependency={dir}{sep}target{sep}debug{sep}deps`
 {compiling} foo v0.0.1 ({url})
 {running} `rustc examples{sep}a.rs --crate-name a --crate-type bin \
         -g \
-        --out-dir {dir}{sep}target{sep}examples \
+        --out-dir {dir}{sep}target{sep}debug{sep}examples \
         --emit=dep-info,link \
-        -L dependency={dir}{sep}target \
-        -L dependency={dir}{sep}target{sep}deps \
-         --extern bar={dir}{sep}target{sep}deps{sep}libbar-[..].rlib`
-{running} `target{sep}examples{sep}a`
+        -L dependency={dir}{sep}target{sep}debug \
+        -L dependency={dir}{sep}target{sep}debug{sep}deps \
+         --extern bar={dir}{sep}target{sep}debug{sep}deps{sep}libbar-[..].rlib`
+{running} `target{sep}debug{sep}examples{sep}a`
 slow1
 slow2
 ",
index 67cd1aec3971325b718639ecba1146c1c7db2717..bde0542dc5ee6ee1f6592d3cbf0b830e9f989905 100644 (file)
@@ -632,7 +632,7 @@ test!(bin_there_for_integration {
             use std::old_io::Command;
             #[test]
             fn test_test() {
-                let status = Command::new("target/foo").status().unwrap();
+                let status = Command::new("target/debug/foo").status().unwrap();
                 assert!(status.matches_exit_status(1));
             }
         "#);